FEXP Solver  1.0.0.0
FEXPMultiGraph.h
Go to the documentation of this file.
1 // © FEXP, FEXPEnterprise Solver, Ing. Vaclav Rek
3 // Graph algorithms.
4 // Compiler must support C++ ver.14 and later
6 #ifndef _CFEXPMULTIGRAPH_H_
7 #define _CFEXPMULTIGRAPH_H_
8 #include "FEXPCommon.h"
9 
16 // primary template
17 template<typename TValue, typename Enable = void>
18 class CFEXPMultiGraph { };
21 template<typename TValue>
23  <TValue, typename std::enable_if_t<std::is_integral<TValue>::value>>
24 {
25 public:
27  virtual ~CFEXPMultiGraph();
28 
29  // add edge to graph
30  void AddEdge(TValue vert1, TValue vert2);
31  // gives map of graphs and their nodes
33  // number of already added vertexes
34  size_t GetEdgeCount() const { return _edge_counter; }
35 protected:
36  // [no protected members] -----------------------------
37 private:
38  size_t _edge_counter;
39  struct vertex
40  {
41  TValue _ID;
42  bool _CLR;
43  std::vector<vertex*> _ADJ;
44  vertex(TValue id) : _ID(id), _CLR(false) { }
45  };
46  std::map<TValue, Ptr<vertex>> _graph_vertx_map;
47  // deep-first search algorithm (DFS)
48  void dfs_recurse(vertex * vert, Ptr<std::map<size_t, std::vector<TValue>>> res_map, size_t g_number);
49  void dfs_not_rcs(vertex * vert, Ptr<std::map<size_t, std::vector<TValue>>> res_map, size_t g_number);
50  bool try_clr_vtx(vertex * vert, Ptr<std::map<size_t, std::vector<TValue>>> res_map, size_t g_number);
51 };
52 
53 //--------------------------------------------------------------------------------------
54 template<typename TValue>
56  : _edge_counter(FEXPCOMMON_DEFAULT_VALUE) { }
57 //--------------------------------------------------------------------------------------
58 
59 //--------------------------------------------------------------------------------------
60 template<typename TValue>
62 //--------------------------------------------------------------------------------------
63 
64 //--------------------------------------------------------------------------------------
65 template<typename TValue>
67  ::AddEdge(TValue vrtx1, TValue vrtx2)
68 //--------------------------------------------------------------------------------------
69 {
70  // vertex -- 1
71  auto vertex1 = Ptr<vertex>();
72  if (!_graph_vertx_map.count(vrtx1))
73  {
75  _graph_vertx_map.insert(MAP_PAIR(vertex1->_ID, vertex1));
76  }
77  else
78  vertex1 = _graph_vertx_map[vrtx1];
79  // vertex -- 2
80  auto vertex2 = Ptr<vertex>();
81  if (!_graph_vertx_map.count(vrtx2))
82  {
84  _graph_vertx_map.insert(MAP_PAIR(vertex2->_ID, vertex2));
85  }
86  else
87  vertex2 = _graph_vertx_map[vrtx2];
88  // create edge
89  vertex1->_ADJ.push_back(vertex2.get());
90  vertex2->_ADJ.push_back(vertex1.get());
91  ++_edge_counter;
92 }
93 
94 //--------------------------------------------------------------------------------------
95 template<typename TValue>
98  ::GetGraphs()
99 //--------------------------------------------------------------------------------------
100 {
101  // check if graph is empty
103  if (_graph_vertx_map.empty())
104  return result;
105  // allocate result
106  result = CFEXPDataManager<std::map<size_t, std::vector<TValue>>>::SafeAllocInstance();
107  // create map of graphs and their vertexes
108  size_t graph_number_generator = 0;
109  FEXPCOMMON_FOREACH_ITER_FNC(_graph_vertx_map, { dfs_not_rcs(IT.second.get(), result, ++graph_number_generator); });
110  // mark all vertexes as not processed (for repeated use of this function for search)
111  FEXPCOMMON_FOREACH_ITER_FNC(_graph_vertx_map, { IT.second->_CLR = false; });
112  return result;
113 }
114 
117 //--------------------------------------------------------------------------------------
118 template<typename TValue>
120  ::dfs_recurse(vertex * vert, Ptr<std::map<size_t, std::vector<TValue>>> res_map, size_t g_number)
121 //--------------------------------------------------------------------------------------
122 {
123  // check if vertex has been already processed
124  if (!try_clr_vtx(vert, res_map, g_number))
125  return;
126  // process new adjacency vertexes
127  FEXPCOMMON_FOREACH_ITER_FNC(vert->_ADJ, { dfs_recurse(IT, res_map, g_number); });
128 }
129 
132 //--------------------------------------------------------------------------------------
133 template<typename TValue>
135  ::dfs_not_rcs(vertex * vert, Ptr<std::map<size_t, std::vector<TValue>>> res_map, size_t g_number)
136 //--------------------------------------------------------------------------------------
137 {
138  std::stack<vertex*> vertex_stack;
139  vertex_stack.push(vert);
140  while (!vertex_stack.empty())
141  {
142  auto current_vert = vertex_stack.top();
143  vertex_stack.pop();
144  // check if vertex has already been processed
145  if (!try_clr_vtx(current_vert, res_map, g_number))
146  continue;
147  // process new adjacency vertexes
148  FEXPCOMMON_FOREACH_ITER_FNC(current_vert->_ADJ, { vertex_stack.push(IT); });
149  }
150 }
151 
152 //--------------------------------------------------------------------------------------
153 template<typename TValue>
155  ::try_clr_vtx(vertex * vert, Ptr<std::map<size_t, std::vector<TValue>>> res_map, size_t g_number)
156 //--------------------------------------------------------------------------------------
157 {
158  // check if vertex has been processed
159  if (vert->_CLR)
160  return false;
161  // check if graph is presented in map,
162  // if not so add it to result
163  if (!res_map->count(g_number))
164  res_map->insert(MAP_PAIR(g_number, std::vector<TValue>()));
165  res_map->at(g_number).push_back(vert->_ID);
166  // mark vertex as processed
167  vert->_CLR = true;
168  return true;
169 }
170 
171 #endif // !_CFEXPMULTIGRAPH_H_
#define IT
Definition: FEXPCommon.h:155
#define FEXPCOMMON_FOREACH_ITER_FNC(data, lambda_body)
Definition: FEXPCommon.h:157
Definition: FEXPCommon.h:276
static Ptr< TType > SafeAllocInstance(VarArgs &&... inpar)
It allocates data.
Definition: FEXPCommon.h:392
Definition: FEXPMultiGraph.h:18
#define MAP_PAIR(key, itm)
Definition: FEXPCommon.h:471
#define FEXPCOMMON_DEFAULT_VALUE
Definition: FEXPCommon.h:179
Smart pointer.
Definition: FEXPCommon.h:274